//
//  AFService.swift
//  BabaLink
//
//  Created by wrs on 2018/7/13.
//  Copyright © 2018年 wrs. All rights reserved.
//

import UIKit
import Alamofire
public let shareSessionManager: SessionManager = {
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders
    configuration.timeoutIntervalForRequest = 20
    return SessionManager(configuration: configuration)
}()

func AFRequest(url: String, requestMethod: CPMethod, params: [String: Any]? = nil, header: [String: String]? = nil, respHandle: CPRespHandle? = nil, cer localCer: Data?)
{
   let manager = shareSessionManager
    manager.delegate.sessionDidReceiveChallenge = { session, challenge in
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { // 认证服务器！
            if let localCertificateData = localCer { // 有证书就认证
                let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
                let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
                let remoteCertificateData
                    = CFBridgingRetain(SecCertificateCopyData(certificate))!
                if (remoteCertificateData.isEqual(localCertificateData) == true) { // 证书一致
                    let credential = URLCredential(trust: serverTrust)
                    challenge.sender?.use(credential, for: challenge)
                    return (.useCredential,
                            URLCredential(trust: serverTrust))
                } else { // 证书不对
                    return (.cancelAuthenticationChallenge, nil)
                }
            } else { // 没有证书就不校验
                return (.performDefaultHandling, nil)
            }
        } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate { //认证客户端证书
//            let identityAndTrust:IdentityAndTrust = extractIdentity();
//            let urlCredential:URLCredential = URLCredential(
//                identity: identityAndTrust.identityRef,
//                certificates: identityAndTrust.certArray as? [AnyObject],
//                persistence: URLCredential.Persistence.forSession);
//
//            return (.useCredential, urlCredential);
            return (.performDefaultHandling, nil)
        } else { // 其它情况（不接受认证）
            return (.cancelAuthenticationChallenge, nil)
        }
    }
    var encoding: ParameterEncoding = URLEncoding.methodDependent
    switch requestMethod {
    case .post:
        encoding = JSONEncoding.default
    default:
        break
    }
    let request: DataRequest = manager.request(url, method: requestMethod, parameters: params, encoding: encoding, headers: header)
    request.responseString(queue: nil, encoding: String.Encoding.utf8) { (response: DataResponse<String>) in
        if let handle = respHandle {
            switch response.result {
            case .success:
                handle(true, response.result.value, nil, response.response?.allHeaderFields)
            case .failure(let error):
                handle(false, response.result.value, error, nil)
            }
        }
    }
//    request.responseString { (response: DataResponse<String>) in
//        if let handle = respHandle {
//            switch response.result {
//            case .success:
//                handle(true, response.result.value, nil)
//            case .failure(let error):
//                 handle(true, response.result.value, error)
//            }
//        }
//    }
//    request.responseJSON { (response: DataResponse<Any>) in
//        if let handle = respHandle {
//            switch response.result {
//            case .success:
//                handle(true, response.result.value, nil)
//            case .failure(let error):
//                if let _ = response.data {
//                    let respStr =  String(data: response.data!, encoding: .utf8)
//                    handle(false, respStr, error)
//                } else {
//                    handle(false, nil, error)
//                }
//            }
//        }
//    }
}

func AFUploadFile(url: String, header: [String: String]? = nil, params: [String: Any]? = nil, file: AnyObject?, fileName: String, key: String, mimeType: String, uploadingHandle:@escaping CPProgressHandle, respHandle: CPRespHandle? = nil) -> Void {
     if let aUrl = URL(string: url) {
        Alamofire.upload(multipartFormData: { (formData) in
            if let f = file {
                if f is Data {
                    formData.append(file as! Data, withName: key, fileName: fileName, mimeType: mimeType)
                } else if f is String {
                    formData.append(URL(fileURLWithPath: file as! String), withName: key, fileName: fileName, mimeType: mimeType)
                } else if f is UIImage {
                    if let data = (file as! UIImage).pngData() {
                        formData.append(data, withName: key, fileName: fileName, mimeType: mimeType)
                    }
                }
            }
            
            if let para = params {
                for (key, value) in para {
                    if let content = value as? String {
                        if let valueData = content.data(using: String.Encoding.utf8) {
                            formData.append(valueData, withName: key)
                        }
                    } else if let file = value as? Data {
                        formData.append(file , withName: key, fileName: fileName, mimeType: mimeType)
                    } else if let file = value as? UIImage {
                        if let data = (file).pngData() {
                            formData.append(data, withName: key, fileName: fileName, mimeType: mimeType)
                        }
                    }
                }
            }
        }, usingThreshold: SessionManager.multipartFormDataEncodingMemoryThreshold, to:aUrl, method: .post, headers: header) { (encodingResult: SessionManager.MultipartFormDataEncodingResult) in
            switch encodingResult {
            case .success(let uploadRequest, _, _):
                uploadRequest.uploadProgress(closure: { (progress: Progress) in
                    uploadingHandle(progress)
                })
                uploadRequest.responseString(completionHandler: { (dataResponse) in
                    if let handle = respHandle {
                        handle(true, dataResponse.result.value, nil, dataResponse.response?.allHeaderFields)
                    }
                })
            case .failure(let error):
                if let handle = respHandle {
                    handle(false, nil, error, nil)
                }
            }
        }
     } else {
        if let handle = respHandle {
            handle(false, nil, nil, nil)
        }
    }
    
}

func AFDownloadFile(url: String, header: [String: String]? = nil, filePath:URL, downloaDingHandle: CPProgressHandle? = nil, respHandle: CPDownloadRespHandle? = nil) -> Void {
    if let aUrl = URL(string: url) {
    let destination: DownloadRequest.DownloadFileDestination = { (resultUrl:URL, resp:HTTPURLResponse) in
        let fileUrl = filePath.appendingPathComponent(resp.suggestedFilename!)
        return (fileUrl, DownloadRequest.DownloadOptions.removePreviousFile)
    }
    Alamofire.download(aUrl, method: .get, parameters: nil, encoding: URLEncoding.default, headers: header, to: destination).downloadProgress { (progress) in
            if let handle = downloaDingHandle {
                handle(progress)
            }
        }.responseData { (response:DownloadResponse<Data>) in
              if let handle = respHandle {
                          switch response.result {
                          case .success:
                              handle(true, response.result.value, response.destinationURL, nil, response.response?.allHeaderFields)
                          case .failure(let error):
                              handle(false, response.result.value, response.destinationURL, error, nil)
                          }
                      }
        }
    } else {
        if let handle = respHandle {
            handle(false, nil, nil, nil, nil)
        }
    }
    
}


//获取客户端证书相关信息
func extractIdentity() -> IdentityAndTrust {
    var identityAndTrust:IdentityAndTrust!
    var securityError:OSStatus = errSecSuccess
    
    let path: String = Bundle.main.path(forResource: "client", ofType: "p12")!
    let PKCS12Data = NSData(contentsOfFile:path)!
    let key : NSString = kSecImportExportPassphrase as NSString
    let options : NSDictionary = [key : "xxxxxxxxxxxx"] //客户端证书密码
    var items : CFArray?
    
    securityError = SecPKCS12Import(PKCS12Data, options, &items)
    
    if securityError == errSecSuccess {
        let certItems:CFArray = items!;
        let certItemsArray:Array = certItems as Array
        let dict:AnyObject? = certItemsArray.first;
        if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
            // grab the identity
            let identityPointer:AnyObject? = certEntry["identity"];
            let secIdentityRef:SecIdentity = identityPointer as! SecIdentity
            // grab the trust
            let trustPointer:AnyObject? = certEntry["trust"]
            let trustRef:SecTrust = trustPointer as! SecTrust
            // grab the cert
            let chainPointer:AnyObject? = certEntry["chain"]
            identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef,
                                                trust: trustRef, certArray:  chainPointer!)
        }
    }
    return identityAndTrust;
}

//定义一个结构体，存储认证相关信息
struct IdentityAndTrust {
    var identityRef:SecIdentity
    var trust:SecTrust
    var certArray:AnyObject
}

